/*
 * Copyright 2006 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.user.client.ui;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;

/**
 * A panel that lays all of its widgets out in a single vertical column.
 * 
 * <p>
 * <img class='gallery' src='VerticalPanel.png'/>
 * </p>
 */
public class VerticalPanel extends CellPanel implements HasAlignment {

  private Element body;
  private HorizontalAlignmentConstant horzAlign = ALIGN_LEFT;
  private VerticalAlignmentConstant vertAlign = ALIGN_TOP;

  /**
   * Creates an empty vertical panel.
   */
  public VerticalPanel() {
    body = DOM.createTBody();
    DOM.appendChild(getTable(), body);

    DOM.setAttribute(getTable(), "cellSpacing", "0");
    DOM.setAttribute(getTable(), "cellPadding", "0");

    setElement(getTable());
  }

  public boolean add(Widget w) {
    return insert(w, getWidgetCount());
  }

  public HorizontalAlignmentConstant getHorizontalAlignment() {
    return horzAlign;
  }

  public VerticalAlignmentConstant getVerticalAlignment() {
    return vertAlign;
  }

  public boolean insert(Widget w, int beforeIndex) {
    if (!super.insert(w, beforeIndex))
      return false;

    Element tr = DOM.createTR();
    Element td = DOM.createTD();

    DOM.insertChild(body, tr, beforeIndex);
    DOM.appendChild(tr, td);
    DOM.appendChild(td, w.getElement());

    DOM.setStyleAttribute(w.getElement(), "position", "static");
    setCellHorizontalAlignment(w, horzAlign);
    setCellVerticalAlignment(w, vertAlign);
    return true;
  }

  public boolean remove(Widget w) {
    if (w.getParent() != this)
      return false;

    Element td = DOM.getParent(w.getElement());
    Element tr = DOM.getParent(td);
    DOM.removeChild(body, tr);

    super.remove(w);
    return true;
  }

  /**
   * Sets the default horizontal alignment to be used for widgets added to this
   * panel. It only applies to widgets added after this property is set.
   * 
   * @see HasHorizontalAlignment#setHorizontalAlignment(HorizontalAlignmentConstant)
   */
  public void setHorizontalAlignment(HorizontalAlignmentConstant align) {
    horzAlign = align;
  }

  /**
   * Sets the default vertical alignment to be used for widgets added to this
   * panel. It only applies to widgets added after this property is set.
   * 
   * @see HasVerticalAlignment#setVerticalAlignment(VerticalAlignmentConstant)
   */
  public void setVerticalAlignment(VerticalAlignmentConstant align) {
    vertAlign = align;
  }

  public void setCellHorizontalAlignment(Widget w,
      HorizontalAlignmentConstant align) {
    Element td = getWidgetTd(w);
    if (td != null) {
      DOM.setAttribute(td, "align", align.getTextAlignString());
    }
  }

  public void setCellVerticalAlignment(Widget w, VerticalAlignmentConstant align) {
    Element td = getWidgetTd(w);
    if (td != null) {
      DOM
        .setStyleAttribute(td, "verticalAlign", align.getVerticalAlignString());
    }
  }

  public void setCellHeight(Widget w, String height) {
    Element td = DOM.getParent(w.getElement());
    DOM.setAttribute(td, "height", height);
  }

  public void setCellWidth(Widget w, String width) {
    Element td = DOM.getParent(w.getElement());
    DOM.setAttribute(td, "width", width);
  }

  private Element getWidgetTd(Widget w) {
    if (w.getParent() != this)
      return null;
    return DOM.getParent(w.getElement());
  }
}
